package com.cloud.tsp.service.impl;

import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.api.domain.user.*;
import com.cloud.api.utils.WebHttpApi;
import com.cloud.core.exception.MyException;
import com.cloud.mybatis.config.LoginHolder;
import com.cloud.mybatis.domain.TableDataInfo;
import com.cloud.tsp.mapper.UserExtendMapper;
import com.cloud.tsp.service.IUserExtendService;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 管理端登陆用户扩展表 服务实现类
 * </p>
 *
 * @author haohaibo
 * @since 2024-08-21
 */
@Service("userExtendService")
public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper, UserExtend> implements IUserExtendService {


    @Resource
    private UserExtendMapper userExtendMapper;
    @Resource(name = "myRedis")
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void insertUser(AddUserRequest para) {
        UserExtend user = userExtendMapper.selectOne(new QueryWrapper<UserExtend>().lambda().eq(UserExtend::getUserName, para.getUserName()));
        if (user != null){
            throw new MyException("validation.exception.user.exist");
        }
        if (StringUtil.isEmpty(para.getUserId())){
            para.setUserId(IdUtil.getSnowflakeNextIdStr());
        }
        String userId = para.getUserId();
        SaveUser saveUser = new SaveUser();
        saveUser.setUid(userId);
        saveUser.setEnable(para.getEnable());
        saveUser.setUsername(para.getUserName());
        saveUser.setMobile(para.getMobile());

        UserExtend userExtend = new UserExtend();
        userExtend.setUserName(para.getUserName());
        userExtend.setUserId(userId);
        userExtend.setName(para.getName());
        userExtend.setDeptId(para.getDeptId());
        userExtend.setMobile(para.getMobile());
        userExtend.setEmail(para.getEmail());
        userExtend.setEnable(para.getEnable());

        SaveAuthority saveAuthority = new SaveAuthority();
        saveAuthority.setUserId(userId);
        saveAuthority.setDeptCode(para.getDeptId());
        saveAuthority.setRoleCode(para.getRoleCode());

        WebHttpApi.post("http://sso-admin/sso-admin/sso/save", saveUser);
        WebHttpApi.post("http://sys-permit/sys-permit/user-dept/saveOrUpdate", saveAuthority);
        this.save(userExtend);
//        redisTemplate.opsForValue().set("user_role:" + userId, para.getRoleCode());
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    @CacheEvict(cacheNames = "login_user", key = "#para.getUserId()",beforeInvocation = true)
    public void updateUser(UpdateUserRequest para) {
        SaveAuthority saveAuthority = new SaveAuthority();
        saveAuthority.setUserId(para.getUserId());
        saveAuthority.setDeptCode(para.getDeptId());
        saveAuthority.setRoleCode(para.getRoleCode());
        WebHttpApi.post("http://sys-permit/sys-permit/user-dept/saveOrUpdate", saveAuthority);

        UserExtend userExtend = new UserExtend();
        userExtend.setUserId(para.getUserId());
        userExtend.setName(para.getName());
        userExtend.setDeptId(para.getDeptId());
        userExtend.setMobile(para.getMobile());
        userExtend.setEmail(para.getEmail());
        this.saveOrUpdate(userExtend);
//        redisTemplate.opsForValue().set("user_role:" + para.getUserId(), para.getRoleCode());
        redisTemplate.opsForValue().set("login_user:" + para.getUserId(), para.getName());
    }

    @Override
    public TableDataInfo<UserResponse> selectUserList(QueryAdminUser para) {
        Page<UserResponse> page = new Page<>(para.getPage(), para.getPageSize());
        Page<UserResponse> data = userExtendMapper.selectUserList(page, para);
        Map<String, String> collect = userExtendMapper.selectList(null).stream().collect(Collectors.toMap(UserExtend::getUserId, UserExtend::getName));
        for (UserResponse record : data.getRecords()) {
            record.setMobile(DesensitizedUtil.mobilePhone(record.getMobile()));
            record.setCreateUser(collect.get(record.getCreateUser()));
            if (StringUtil.isNotBlank(record.getEmail())){
                int i = record.getEmail().indexOf("@");
                record.setEmail(StrUtil.hide(record.getEmail(),1,i));
            }
        }
        return TableDataInfo.build(data);
    }

    @Override
    public UserResponse selectLoginUserInfo() {
        String uid = LoginHolder.getLoginUser().getUid();
        return userExtendMapper.selectLoginUserInfo(uid);
    }

    @Override
    public void updateLoginUserInfo(UpdateUserInfo para) {
        String uid = LoginHolder.getLoginUser().getUid();
        UserExtend userExtend = new UserExtend();
        userExtend.setUserId(uid);
        userExtend.setEmail(para.getEmail());
        userExtend.setMobile(para.getMobile());
        this.saveOrUpdate(userExtend);
    }

    @Override
//    @Cacheable(cacheNames = "login_user", key = "#userId",unless = "#result == null")
    public UserExtend selectLoginUser(String userId) {
        UserExtend userExtend = userExtendMapper.selectById(userId);
        return userExtend;
    }

    @Override
    public List<UserRole> selectUserRole() {
        return userExtendMapper.selectUserRole();
    }
}